package com.godpaper.the5elements.util
{
	import com.godpaper.the5elements.model.BoardModel;
	import com.godpaper.the5elements.model.PiecesModel;
	import com.godpaper.the5elements.views.components.GasketButton;
	
	import jp.dip.hael.gameai.graph.Edge;
	import jp.dip.hael.gameai.graph.searcher.BFS;
	import jp.dip.hael.gameai.graph.searcher.DFS;
	
	import mx.collections.ArrayCollection;
	import mx.logging.ILogger;
	import mx.logging.Log;
	
	
	public class PositionTransactUtil
	{
		private static const log:ILogger = mx.logging.Log.getLogger("PositionTransactUtil");
		/**
		 * Construtor is only for testint func unit. 
		 */		
		public function PositionTransactUtil()
		{
			for(var i:int=0;i<12;i++)
			{
				trace(PositionTransactUtil.transactIndex2Array(i),"\n");
			}
		}
		/**
		 * 
		 * @param graphNodeIndex,such as 0~11;
		 * @return graphNodePosition,such as [1,1];
		 * 
		 */		
		public static function transactIndex2Array(index:int):Array
		{
			var result:Array = [-1,-1];
			if(0<=index && index<=1)
			{
				result = [index,1];	
			}else if(1<index && index<6)
			{
				result = [index-1,2];
			}else if(index>=6 && index<10)
			{
				result = [index-5,3];
			}else if(index>=10 && index<13)
			{
				result = [index-8,4];
			}
			return result;
		}
		/**
		 * 
		 * @param graphNodePosition,such as [1,1];
		 * @return graphNodeIndex,such as 0~11;
		 * 
		 */		
		public static function transactArray2Index(position:Array):int//gasket button position to index.
		{
			var result:int=-1;//why -1?it equals to gamePosition's boundary;
			switch(position[1])
			{
				case 1:
					if(position[0]!=0 || position[0]!=5)
					{
						result = position[0]-2; 
					}
					break;
				case 2:
				case 3:
					result = position[0]+(position[1]-2)*4+1 ; 
					break;
				case 4:
					if(position[0]!=0 || position[0]!=5)
					{
						result = position[0]+8;
					}	
					break;
				default:
					break;			
			}
			return result;
		}
		/**
		 * 
		 * @param walkableGBs
		 * @return in walkableGBs's fireGBs( existed at least of 3PiecesButtons linked simple path ).
		 * 
		 */		
		public static function doesWalkableGBsIsLinkable(walkableGBs:ArrayCollection):ArrayCollection
		{
			var fireGBs:ArrayCollection = new ArrayCollection();
			//todo: analylize 3+free gasketButton' simple tree structe,
			// such as:
			//-----------------------------
			// * * *
			//-----------------------------
			// * * // * * //   * // *   //
			// *   //   * // * * // * * //
			//-----------------------------
			// *
			// *
			// *
			//-----------------------------
			var cIndex:int = PositionTransactUtil.transactArray2Index( PiecesModel.getInstance().selectedPiece.pieceVO.position );
			log.debug("cIndex@doesWalkableGBsIsLinkable:{0}",cIndex);
			for(var i:int=0;i<walkableGBs.length;i++)
			{
				var searcher:DFS = new DFS(BoardModel.getInstance().gameGraph);
				var terminalIndex:int = int(walkableGBs.getItemAt(i));
				log.debug("terminalIndex in linkableGBs:{0}",terminalIndex);
				searcher.search(cIndex,terminalIndex);
				if(searcher.path.length==3)
				{
					log.debug("Found this paths make up the5elements:{");
					for(var j:int=0;j<searcher.path.length;j++)
					{
						log.debug( "\t{0}",(searcher.path[j] as Edge).dump() );
					}
					log.debug("\n}");
					var fireGBnodeIndex:int = (searcher.path[2] as Edge).dst;
					var fireGBnodePosition:Array = PositionTransactUtil.transactIndex2Array(fireGBnodeIndex);
					log.debug("fireGBnodeIndex:{0},fireGBnodePosition:{1}",fireGBnodeIndex,fireGBnodePosition);
					fireGBs.addItem( BoardModel.getInstance().gasketsPosition.gett( fireGBnodePosition[0],
																				    fireGBnodePosition[1] ));
				}
			}
			return fireGBs;
		}
		/**
		 * 
		 * @param startGB
		 * @param endGB
		 * @return whether startGB and endGB is reachable.
		 * 
		 */		
		public static function doseEnabledGBsIsWalkable(startGB:GasketButton,endGB:GasketButton):Boolean
		{
			log.info("doseEnabledGBsIsWalkable()");
//			var searcher:DFS = new DFS(BoardModel.getInstance().gameGraph);
			var searcher:BFS = new BFS(BoardModel.getInstance().gameGraph);
			var startIndex:int = PositionTransactUtil.transactArray2Index( startGB.position );
			var endIndex:int = PositionTransactUtil.transactArray2Index( endGB.position );
			log.debug("startIndex:{0},endIndex:{1}",startIndex,endIndex);
			searcher.search( startIndex,endIndex);
			if(searcher.path.length<=0)
			{
				return false;
			}else if(searcher.path.length>0 && searcher.path.length<5)
			{
				for(var p:int=0;p<searcher.path.length;p++)
				{
					if(! BoardModel.getInstance().walkableGBindexs.contains( (searcher.path[p] as Edge).dst) )
					{
						BoardModel.getInstance().walkableGBindexs.addItem( (searcher.path[p] as Edge).dst );
					}
					log.debug("findPath(s):{0}",searcher.path[p].dump());
				}
				log.debug("BoardModel.getInstance().walkableGBindexs:{0}",BoardModel.getInstance().walkableGBindexs);
			}else
			{
				return false;
			}
			return true;
		}
	}
}